/*
 * Copyright (C), 2013-2016, 猎上网
 * FileName: GeneratorUtil.java
 * Author:   kui.zhang
 * Date:     2016年10月21日 上午11:28:14
 * Description: //模块目的、功能描述      
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package site.util;

import org.mybatis.generator.config.ColumnOverride;
import org.mybatis.generator.config.CommentGeneratorConfiguration;
import org.mybatis.generator.config.Context;
import org.mybatis.generator.config.GeneratedKey;
import org.mybatis.generator.config.JDBCConnectionConfiguration;
import org.mybatis.generator.config.JavaClientGeneratorConfiguration;
import org.mybatis.generator.config.JavaModelGeneratorConfiguration;
import org.mybatis.generator.config.JavaTypeResolverConfiguration;
import org.mybatis.generator.config.ModelType;
import org.mybatis.generator.config.PluginConfiguration;
import org.mybatis.generator.config.SqlMapGeneratorConfiguration;
import org.mybatis.generator.config.TableConfiguration;

import java.util.ArrayList;
import java.util.List;

/**
 * 〈一句话功能简述〉<br>
 * pojo工具生成类
 *
 * @author kui.zhang
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
public class GeneratorUtil {
    private static String contextId = "ho";
    private static String javaFileEncoding = "UTF-8";
    private static String targetRuntime = "MyBatis3";
    private static String targetProjectXml = "src/main/resources";
    private static String targetProjectJava = "src/main/java";
    private static String targetPackage = "com.hunteron.tbbb";
    private static String mybatisPackage = "mybatis.sqlmap.tbbb";
    private static String sqlStatement = "SELECT LAST_INSERT_ID()";
    private static ModelType modelType = ModelType.FLAT;
    private static boolean generatedKey = true;
    private static boolean useActualColumnNames = true;
    private static String[] plugins = { "site.util.ModelExampleLimitPlugin", "site.util.ModelJavaDocPlugin",
            "org.mybatis.generator.plugins.SerializablePlugin" };
    private String jdbcUrl = null;
    private String jdbcDriver = null;
    private String jdbcPassword = null;
    private String jdbcUserName = null;
    private static boolean enableSubPackages = false;

    public GeneratorUtil(String _jdbcUrl, String _jdbcDriver, String _jdbcUserName, String _jdbcPassword) {
        jdbcUrl = _jdbcUrl;
        jdbcDriver = _jdbcDriver;
        jdbcUserName = _jdbcUserName;
        jdbcPassword = _jdbcPassword;
    }

    public JDBCConnectionConfiguration getJDBCConnectionConfiguration() {
        JDBCConnectionConfiguration JdbcConnectionConfiguration = new JDBCConnectionConfiguration();
        JdbcConnectionConfiguration.setConnectionURL(jdbcUrl);
        JdbcConnectionConfiguration.setDriverClass(jdbcDriver);
        JdbcConnectionConfiguration.setPassword(jdbcPassword);
        JdbcConnectionConfiguration.setUserId(jdbcUserName);
        return JdbcConnectionConfiguration;
    }

    public static JavaClientGeneratorConfiguration getJavaClientGeneratorConfiguration() {
        JavaClientGeneratorConfiguration jcgc = new JavaClientGeneratorConfiguration();
        jcgc.setConfigurationType("XMLMAPPER");
        jcgc.setTargetPackage(targetPackage + ".mapper");
        jcgc.setTargetProject(targetProjectJava);
        jcgc.addProperty("enableSubPackages", enableSubPackages == true ? "true" : "false");
        return jcgc;
    }

    public static SqlMapGeneratorConfiguration getSqlMapGeneratorConfiguration() {
        SqlMapGeneratorConfiguration smgc = new SqlMapGeneratorConfiguration();
        smgc.addProperty("enableSubPackages", enableSubPackages == true ? "true" : "false");
        smgc.setTargetPackage(mybatisPackage);
        smgc.setTargetProject(targetProjectXml);
        return smgc;
    }

    public static JavaModelGeneratorConfiguration getJavaModelGeneratorConfiguration() {
        JavaModelGeneratorConfiguration jmgc = new JavaModelGeneratorConfiguration();
        jmgc.addProperty("enableSubPackages", enableSubPackages == true ? "true" : "false");
        jmgc.addProperty("trimStrings", "true");
        jmgc.setTargetPackage(targetPackage + ".model");
        jmgc.setTargetProject(targetProjectJava);
        return jmgc;
    }

    public static TableConfiguration getTableConfiguration(String tableName, String domainObjectName, List<ColumnOverrideModel> columnOverrideModels) {
        TableConfiguration tc = new TableConfiguration(new Context(modelType));
        tc.setTableName(tableName);
        tc.setDomainObjectName(domainObjectName);

        if (generatedKey) {
            tc.setGeneratedKey(getGeneratedKey());
        }
        if (useActualColumnNames) {
            tc.addProperty("useActualColumnNames", "false"); // 支持驼峰形式、false 不支持（可以添加、自定义重写列）
        } else {
            tc.addProperty("useActualColumnNames", "true");
            List<ColumnOverride> columnOverrides = getColumnOverrideList(columnOverrideModels);
            for (ColumnOverride co : columnOverrides) {
                tc.addColumnOverride(co);
            }
        }
        return tc;
    }

    public static List<ColumnOverride> getColumnOverrideList(List<ColumnOverrideModel> columnOverrideModels) {
        if (columnOverrideModels == null || columnOverrideModels.size() <= 0)
            return null;
        List<ColumnOverride> columnOverrides = new ArrayList<ColumnOverride>();
        for (ColumnOverrideModel columnOverrideModel : columnOverrideModels) {
            if (columnOverrideModel.getColumnName() != null && !("").equals(columnOverrideModel)) {
                ColumnOverride co = new ColumnOverride(columnOverrideModel.getColumnName());
                if (columnOverrideModel.getColumnName() != null)
                    co.setJavaProperty(columnOverrideModel.getJavaProperty());
                if (columnOverrideModel.getJavaType() != null)
                    co.setJavaType(columnOverrideModel.getJavaType());
                if (columnOverrideModel.getJdbcType() != null)
                    co.setJdbcType(columnOverrideModel.getJdbcType());
                columnOverrides.add(co);
            }
        }
        return columnOverrides;
    }

    public static GeneratedKey getGeneratedKey() {
        GeneratedKey gk = new GeneratedKey(contextId, sqlStatement, true, "post");
        return gk;
    }

    public static CommentGeneratorConfiguration getCommentGeneratorConfiguration() {
        CommentGeneratorConfiguration cgc = new CommentGeneratorConfiguration();
        cgc.addProperty("suppressDate", "true");
        cgc.addProperty("suppressAllComments", "true");
        return cgc;
    }

    public static JavaTypeResolverConfiguration getJavaTypeResolverConfiguration() {
        JavaTypeResolverConfiguration jtrc = new JavaTypeResolverConfiguration();
        jtrc.addProperty("forceBigDecimals", "true");
        return jtrc;
    }

    public Context context(String tableName, String domainObjectName, List<ColumnOverrideModel> columnOverrideModels) {
        Context context = new Context(modelType);
        for (String plugin : plugins) {
            PluginConfiguration pcf = new PluginConfiguration();
            pcf.setConfigurationType(plugin);
            context.addPluginConfiguration(pcf);
        }
        context.setId(contextId);
        context.addProperty("javaFileEncoding", javaFileEncoding);
        context.setJdbcConnectionConfiguration(getJDBCConnectionConfiguration());
        context.setJavaClientGeneratorConfiguration(getJavaClientGeneratorConfiguration());
        context.setSqlMapGeneratorConfiguration(getSqlMapGeneratorConfiguration());
        context.setJavaModelGeneratorConfiguration(getJavaModelGeneratorConfiguration());
        context.setTargetRuntime(targetRuntime);
        context.setCommentGeneratorConfiguration(getCommentGeneratorConfiguration());
        context.addTableConfiguration(getTableConfiguration(tableName, domainObjectName, columnOverrideModels));
        context.setJavaTypeResolverConfiguration(getJavaTypeResolverConfiguration());
        return context;
    }

    /**
     * @param contextId the contextId to set
     */
    public static void setContextId(String contextId) {
        GeneratorUtil.contextId = contextId;
    }

    /**
     * @param javaFileEncoding the javaFileEncoding to set
     */
    public static void setJavaFileEncoding(String javaFileEncoding) {
        GeneratorUtil.javaFileEncoding = javaFileEncoding;
    }

    /**
     * @param targetRuntime the targetRuntime to set
     */
    public static void setTargetRuntime(String targetRuntime) {
        GeneratorUtil.targetRuntime = targetRuntime;
    }

    /**
     * 包根目录
     * 
     * eg: "com.hunteron.tbbb"
     */
    public static void setTargetPackage(String targetPackage) {
        GeneratorUtil.targetPackage = targetPackage;
    }

    /**
     * xml 文件生成目录
     * 
     * eg: "mybatis.sqlmap.tbbb"
     */
    public static void setMybatisPackage(String mybatisPackage) {
        GeneratorUtil.mybatisPackage = mybatisPackage;
    }

    /**
     * @param sqlStatement the sqlStatement to set
     */
    public static void setSqlStatement(String sqlStatement) {
        GeneratorUtil.sqlStatement = sqlStatement;
    }

    /**
     * @param modelType the modelType to set
     */
    public static void setModelType(ModelType modelType) {
        GeneratorUtil.modelType = modelType;
    }

    /**
     * @param generatedKey the generatedKey to set
     */
    public static void setGeneratedKey(boolean generatedKey) {
        GeneratorUtil.generatedKey = generatedKey;
    }

    /**
     * @param useActualColumnNames the useActualColumnNames to set
     */
    public static void setUseActualColumnNames(boolean useActualColumnNames) {
        GeneratorUtil.useActualColumnNames = useActualColumnNames;
    }

    /**
     * @param plugins the plugins to set
     */
    public static void setPlugins(String[] plugins) {
        GeneratorUtil.plugins = plugins;
    }

    /**
     * @param jdbcUrl the jdbcUrl to set
     */
    public void setJdbcUrl(String jdbcUrl) {
        this.jdbcUrl = jdbcUrl;
    }

    /**
     * @param jdbcDriver the jdbcDriver to set
     */
    public void setJdbcDriver(String jdbcDriver) {
        this.jdbcDriver = jdbcDriver;
    }

    /**
     * @param jdbcPassword the jdbcPassword to set
     */
    public void setJdbcPassword(String jdbcPassword) {
        this.jdbcPassword = jdbcPassword;
    }

    /**
     * @param jdbcUserName the jdbcUserName to set
     */
    public void setJdbcUserName(String jdbcUserName) {
        this.jdbcUserName = jdbcUserName;
    }

    /**
     * @param enableSubPackages the enableSubPackages to set
     */
    public static void setEnableSubPackages(boolean enableSubPackages) {
        GeneratorUtil.enableSubPackages = enableSubPackages;
    }

    /**
     * @param targetProjectXml the targetProjectXml to set
     */
    public static void setTargetProjectXml(String targetProjectXml) {
        GeneratorUtil.targetProjectXml = targetProjectXml;
    }

    /**
     * @param targetProjectJava the targetProjectJava to set
     */
    public static void setTargetProjectJava(String targetProjectJava) {
        GeneratorUtil.targetProjectJava = targetProjectJava;
    }

}
